/**
 * Created by a on 2016/10/13.
 */
var express = require('express');
var fs=require('fs');
var opt=require('./opt.json');
var ca=require('../routes/calib.js');
var cmn=require('../routes/comn.js');
var parse=require('../rtcm/parse_distrib.js');
var posend=require('../pvtpos/posend.js');

var request=require('request');
var router = express.Router();

var para={
    "sta_id":global.argv.sta_id,
    "rb":loadrb(global.argv.sta_id),
    "len":global.argv.len,
    "buff":new Buffer(global.argv.len*2),
    "index":0,
    "bt":cmn.epoch2time(cmn.str2time(global.argv.bt)),
    "et":cmn.epoch2time(cmn.str2time(global.argv.et)),
    "count":0
};
/*var para={
    "sta_id":0,
    "rb":[],
    "len":0,
    "buff":[],
    "index":0,
    "bt":[],
    "et":[],
    "count":0
};*/
var cont = new cont_create();
function loadrb(sta_id) {
    request(opt.rb_url + "?sta_id=" + sta_id, function (error, response, data) {
        if (error) {
            console.log(error.message);
            process.exit(1);
        }
        else {
            if(response.statusCode==400) {
                console.log(data);
                process.exit(1);
            }
            para.rb = data;
        }
    });
}
function fail_create() {
    this.type=-1;
    this.startTime=new Date();
    this.outageDuration=1;
    this.notes="";
}
function accu_create() {
    this.X=[0];
    this.Y=[0];
}
function timeset(time) {
    var t=new Date(time.time*1000);
    var ep=[t.getFullYear(),t.getMonth(),t.getDate(),0,0,0];
    return cmn.epoch2time(ep);
}
function acc95_create(time) {
    this.time=new timeset(time);
    this.mean=0;
    this.sigma=0;
    this.count=0;
}
function cont_create() {
    this.startTime=0;
    this.Horizontal=new accu_create();
    this.Vertical=new accu_create();
    this.Hori95=[];
    this.Vert95=[];
    this.contEvent=new Array();
}
function acc_struct(Hori,Vert) {
    this.Hori=Hori;
    this.Vert=Vert;
}
function acc95_struct(Hori,Vert) {
    var i,j;
    var acc95={"Hori":{"X":[],"Y":[]},
        "Vert":{"X":[],"Y":[]}};
    for(i=0;i<Hori.length;i++){
        acc95.Hori.X.push(cmn.dayofyear(Hori[i].time));
        acc95.Hori.Y.push(Hori[i].mean+math.sqrt(Hori[i].sigma)*2);
    }
    for(i=0;i<Vert.length;i++){
        acc95.Vert.X.push(cmn.dayofyear(Vert[i].time));
        acc95.Vert.Y.push(Vert[i].mean+math.sqrt(Vert[i].sigma)*2);
    }
    return acc95;
}
router.post('/sta_id',function (req,res) {
    var sta=req.body;
    request(opt.rb_url+"?sta_id="+sta.sta_id, function (error, response, data) {
        if (error) {
            console.log(error);
            res.status(400).send("no this reference coordinate");
        }
        else {
            para.rb = data;
            if(data[0]!=0 && data[1]!=0 && data[2]!=0){
                res.send("ok");
            }
            else{
                res.status(400).send("no this reference coordinate");
            }
        }
    });
    para.sta_id=sta.sta_id;
    para.len=sta.len;
    para.buff=new Buffer(para.len*2);
    para.bt=cmn.epoch2time(sta.bt);
    para.et=cmn.epoch2time(sta.et);
});
router.post('/add',function (req,res) {
    try {
        var data=req.body;
        data.copy(para.buff,para.index,0,data.length);
        para.index+=data.length;
        var sta_data;
        while((sta_data=parse.postdata(para))!=-1) {
            var posR = posend.postpos(para.sta_id, sta_data, para);
            var dH = math.sqrt(posR.dX * posR.dX + posR.dY * posR.dY);
            var dV = posR.dZ;
            var df;
            var time = cmn.gpst2time(posR.week, posR.tow);

            if (posR.posNum < posR.navsys.length + 3) {
                var fail = new fail_create();
                fail.type = opt.svLack;
                fail.startTime = time;
                cont.contEvent.push(fail);
            }
            if (dH >= opt.Herr) {
                var fail = new fail_create();
                fail.type = opt.Herr_exceed;
                fail.startTime = time;
                cont.contEvent.push(fail);
            }
            if (posR.HPL >= opt.HAL) {
                var fail = new fail_create();
                fail.type = opt.HPL_exceed;
                fail.startTime = time;
                cont.contEvent.push(fail);
            }
            accuracyUpdate(cont.Horizontal.X, cont.Horizontal.Y, dH);
            accuracyUpdate(cont.Vertical.X, cont.Vertical.Y, dV);
            accu95Update(cont.Hori95, time, dH);
            accu95Update(cont.Vert95, time, dV);
            if (cont.startTime == 0)
                cont.startTime = time;
            if (opt.isOutage && (df = cmn.timediff(time, cont.startTime)) > opt.accu_val) {
                var fail = new fail_create();
                fail.type = opt.trans_outage;
                fail.startTime = cont.startTime;
                fail.outageDuration = df;
                cont.contEvent.push(fail);
            }
            cont.startTime = time;
        }
        res.send('ok');
    }catch(err){
        res.status(400).send(err.message);
    }
});
router.get('/get_acc',function (req,res) {
    var acc=new acc_struct(cont.Horizontal,cont.Vertical);
    res.send(acc);
});
router.get('/get_acc95',function (req,res) {
    var acc=acc95_struct(cont.Hori95,cont.Vert95);
    res.send(acc);
});
router.get('/get_integrity',function (req,res) {
    res.send(cont.contEvent);
});
router.get('/get_continue',function (req,res) {
    var MTBF;
    MTBF=cmn.timediff(cont.currentTime,cont.startTime).time/3600;
    if(cont.contEvent.length==0)
        res.send(1);
    else
        res.send(1-1/(MTBF/cont.contEvent.length));
});
router.get('/get_available',function (req,res) {
    var MTBO,MTTR=0;
    MTBO=cmn.timediff(cont.currentTime,cont.startTime).time;
    for(var i=0;i<cont.contEvent.length;i++){
        MTTR+=cont.contEvent[i].outageDuration;
    }
    if(cont.contEvent.length==0)
        res.send(1);
    else
        res.send(MTBO/(MTBO+MTTR/(cont.contEvent.length)));
});

function accuracyUpdate(X,Y,dd) {
    var i,j,h;
    for(i=0;i<X.length;i++){
        if(math.abs(X[i]-dd)<=opt.accu_val){
            Y[i]++;
            break;
        }
        if(X[i]-dd>opt.accu_val){
            if(i>0)
                h=X[i-1];
            else
                h=X[i];
            while(h<=dd){
                h+=opt.accu_val;
            }
            X.splice(i,0,h);
            Y.splice(i,0,1);
        }
    }
    if(i==X.length){
        h=X[X.length-1];
        while(h<=dd){
            h+=opt.accu_val;
        }
        X.push(h);
        Y.push(1);
    }
}
function accu95Update(acc95,time,dd) {
    var acc;
    if(acc95.length>0)
        acc=acc95[acc95.length-1];
    if(acc95.length==0 || cmn.timediff(time,acc.time)>24*3600){
        acc=new acc95_create(time);
        acc.mean=dd;
        acc.sigma=0;
        acc.count++;
        acc95.push(acc);
        return;
    }
    acc.mean=cmn.Average(dd,acc.mean,acc.count);
    acc.sigma=cmn.vare(dd,acc.sigma,acc.count,acc.mean);
    acc.count++;
}
function callback(error, response, data) {
    if (error) {
        console.log(error);
    }
    else {
        try {
            para.rb = data;
        } catch (err) {
            console.log(err.message);
        }
    }
}
module.exports = router;